package cl.foursoft.eee.dao.implementation.postgresql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import cl.foursoft.eee.dao.implementation.DBBase;
import cl.foursoft.eee.dao.interfaces.IMaterial;
import cl.foursoft.eee.dao.interfaces.ISeccion;
import cl.foursoft.eee.dao.transferObject.SeccionTO;
import cl.foursoft.eee.util.UtilLog;

public class SeccionDB extends DBBase implements ISeccion {

	
	public SeccionDB (Connection c){
		this.conn = c;
	}
	
	
	@Override
	public List<SeccionTO> obtenerSecciones() {
		
		List<SeccionTO> resp = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String nombreSeccionPadre ;
		
		
		//Devuelve las categrias principales
		String query = " SELECT nombre_seccion_envolvente, id_tipo_seccion_envolvente " +
						"FROM TIPO_SECCION_ENVOLVENTE " +
						"WHERE id_tipo_seccion_envolvente = id_tipo_seccion_envolvente_padr";
		
		try {
			pstmt = this.conn.prepareStatement(query);
			//where
			rs = pstmt.executeQuery();
			resp = new ArrayList<SeccionTO>();
			int idPadre;
			
			while(rs.next()){
				SeccionTO seccion = new SeccionTO();
				
				
				nombreSeccionPadre = rs.getString(1);
				idPadre = rs.getInt(2);
				
				seccion.setIdSeccionPadre(idPadre);
				seccion.setIdTipoSeccion(idPadre);
				seccion.setNombre_seccion_padre(nombreSeccionPadre); 
				seccion.setNombreTipo(nombreSeccionPadre);
				
				seccion.setSeccionesHijo(this.obtenerSeccionesHijosPorId(idPadre,nombreSeccionPadre));
			 
				resp.add(seccion); // 
				
			}
			
			
			rs.close();
			pstmt.close();
			
			
			
		} catch (SQLException e) {
			UtilLog.registrar(e);
		 
		}
		finally{
			if(pstmt!=null){
				try{
					if(rs!=null)
						rs.close();
					pstmt.close();
				}catch (SQLException sqle){
					UtilLog.registrar(sqle);
				} 
			}
		}

		
		
		return resp;
	}
	public List<SeccionTO> obtenerSeccionesPadre() {
		
		List<SeccionTO> resp = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String nombreSeccionPadre ;
		
		
		//Devuelve las categrias principales
		String query = " SELECT nombre_seccion_envolvente, id_tipo_seccion_envolvente " +
		"FROM TIPO_SECCION_ENVOLVENTE " +
		"WHERE id_tipo_seccion_envolvente = id_tipo_seccion_envolvente_padr";
		
		try {
			pstmt = this.conn.prepareStatement(query);
			//where
			rs = pstmt.executeQuery();
			resp = new ArrayList<SeccionTO>();
			int idPadre;
			
			while(rs.next()){
				SeccionTO seccion = new SeccionTO();
				
				nombreSeccionPadre = rs.getString(1);
				idPadre = rs.getInt(2);
				
				seccion.setIdSeccionPadre(idPadre);
				seccion.setIdTipoSeccion(idPadre);
				seccion.setNombre_seccion_padre(nombreSeccionPadre); 
				seccion.setNombreTipo(nombreSeccionPadre);
				
				resp.add(seccion); // 
			}
			
			rs.close();
			pstmt.close();
			
		} catch (SQLException e) {
			UtilLog.registrar(e);
			
		}
		finally{
			if(pstmt!=null){
				try{
					if(rs!=null)
						rs.close();
					pstmt.close();
				}catch (SQLException sqle){
					UtilLog.registrar(sqle);
				} 
			}
		}
		
		
		
		return resp;
	}

	public List<SeccionTO> obtenerSeccionesHijosPorId(int idSeccionPadre,String seccionPadre){
		List<SeccionTO> resp = null;
		
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		
		String query = " SELECT id_tipo_seccion_envolvente, nombre_seccion_envolvente " +
				"FROM TIPO_SECCION_ENVOLVENTE " +
				"WHERE id_tipo_seccion_envolvente_padr = ? and id_tipo_seccion_envolvente_padr!=id_tipo_seccion_envolvente ";
		
		try{
			
			pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, idSeccionPadre);	
			
			rs = pstmt.executeQuery();
			
			resp = new ArrayList<SeccionTO>();
			
			while(rs.next()){
				SeccionTO _nuevaSeccion = new SeccionTO();
				_nuevaSeccion.setIdTipoSeccion(rs.getInt(1));
				_nuevaSeccion.setIdSeccionPadre(idSeccionPadre);
				_nuevaSeccion.setNombreTipo(rs.getString(2));
				_nuevaSeccion.setNombre_seccion_padre(seccionPadre);				
				resp.add(_nuevaSeccion);
				}
		
			
			
			pstmt.close();
			rs.close();
			
		}catch (Exception e) {
			UtilLog.registrar(e);
			
		}
		finally{
			if(pstmt!=null){
				try{
					if(rs!=null)
						rs.close();
					pstmt.close();
				}
				catch (SQLException sqle) {
					UtilLog.registrar(sqle);
				}
			}
		}
		
		
		
		return resp;
	}
	@Override
	public int guardarSeccionesEdificio(List<SeccionTO> seccionesEnvolvente, int idEdificio) {
		int resp = -1;
		List<SeccionTO> seccionesHijo = null;
		PreparedStatement pstmt = null;
		SeccionTO seccionActual;
		IMaterial materiales = new MaterialDB(conn); //Ir a FacadeMateriales
 		SeccionTO seccionActualHijo; 
		String query = "INSERT INTO SECCIONES_ENVOLVENTE_EDIFICIO(" +
									" id_seccion, " +
									"id_edificio, " +
									"id_tipo_seccion_envolvente, " +
									"id_tipo_seccion_envolvente_padr, " +
									"area_seccion )" +
									"VALUES(?,?,?,?,?);"; 
		try{
			pstmt = this.conn.prepareStatement(query);
			
			for (int i = 0 ; i< seccionesEnvolvente.size() ; i++ ){
				seccionActual = seccionesEnvolvente.get(i);
				seccionesHijo = seccionActual.getSeccionesHijo();
				for (int j = 0 ; j< seccionesHijo.size() ; j++ ){
					seccionActualHijo = seccionesHijo.get(j);
					 
					pstmt.setInt(1,seccionActualHijo.getIdSeccion());
					pstmt.setInt(2,idEdificio );
					pstmt.setInt(3,seccionActualHijo.getIdTipoSeccion());
					pstmt.setInt(4,seccionActualHijo.getIdSeccionPadre());
					pstmt.setFloat(5,seccionActualHijo.getArea());
					
					

					resp  =  pstmt.executeUpdate();
				}
				//Guardar Materiales
				if(resp>0 && seccionActual.getComposicion().size()>0) 
					resp = materiales.guardarComposicionEdificio(seccionActual.getComposicion(),seccionActual.getIdSeccionPadre(), idEdificio);
				if(resp>0)
					resp = materiales.guardarParametroComposicion(seccionActual, idEdificio);
			}
			resp = (resp>0) ? 1 : resp;
			pstmt.close();
			
		}catch(Exception e){
			UtilLog.registrar(e);
		}
		finally{
			if(pstmt!=null){
				try{
					pstmt.close();
				}catch(SQLException sqle){
					UtilLog.registrar(sqle);
				}
			}
		}
		
		
		return resp;
	}
	private int actualizarSeccionesEdificio(List<SeccionTO> seccionesEnvolvente, int idEdificio) {
		int resp = -1;
		List<SeccionTO> seccionesHijo = null;
		PreparedStatement pstmt = null;
		SeccionTO seccionActual;
		IMaterial materiales = new MaterialDB(conn); //Ir a FacadeMateriales
		SeccionTO seccionActualHijo; 
		String query = "INSERT INTO SECCIONES_ENVOLVENTE_EDIFICIO(" +
		" id_seccion, " +
		"id_edificio, " +
		"id_tipo_seccion_envolvente, " +
		"id_tipo_seccion_envolvente_padr, " +
		"area_seccion )" +
		"VALUES(?,?,?,?,?);"; 
		String queryActualizar = "UPDATE SECCIONES_ENVOLVENTE_EDIFICIO SET" +
		" id_seccion, " +
		"id_edificio, " +
		"id_tipo_seccion_envolvente, " +
		"id_tipo_seccion_envolvente_padr, " +
		"area_seccion )" +
		"WHERE id_edificio = ? and id_"; 
		try{
			pstmt = this.conn.prepareStatement(query);
			
			for (int i = 0 ; i< seccionesEnvolvente.size() ; i++ ){
				seccionActual = seccionesEnvolvente.get(i);
				seccionesHijo = seccionActual.getSeccionesHijo();
				for (int j = 0 ; j< seccionesHijo.size() ; j++ ){
					seccionActualHijo = seccionesHijo.get(j);
					
					pstmt.setInt(1,seccionActualHijo.getIdSeccion());
					pstmt.setInt(2,idEdificio );
					pstmt.setInt(3,seccionActualHijo.getIdTipoSeccion());
					pstmt.setInt(4,seccionActualHijo.getIdSeccionPadre());
					pstmt.setFloat(5,seccionActualHijo.getArea());
					
					
					
					resp  =  pstmt.executeUpdate();
				}
				//Guardar Materiales
				if(resp>0 && seccionActual.getComposicion().size()>0) 
					resp = materiales.guardarComposicionEdificio(seccionActual.getComposicion(),seccionActual.getIdSeccionPadre(), idEdificio);
				if(resp>0)
					resp = materiales.guardarParametroComposicion(seccionActual, idEdificio);
			}
			resp = (resp>0) ? 1 : resp;
			pstmt.close();
			
		}catch(Exception e){
			UtilLog.registrar(e);
		}
		finally{
			if(pstmt!=null){
				try{
					pstmt.close();
				}catch(SQLException sqle){
					UtilLog.registrar(sqle);
				}
			}
		}
		
		
		return resp;
	}
	
	public List<SeccionTO> obtenerSeccionesEdificio(int idEdificio){

		List<SeccionTO> resp = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		IMaterial materiales = new MaterialDB(conn);
		
		String nombreSeccionPadre ;
		
		
		//Devuelve las categrias principales
		String query = " SELECT nombre_seccion_envolvente, id_tipo_seccion_envolvente " +
						"FROM TIPO_SECCION_ENVOLVENTE " +
						"WHERE id_tipo_seccion_envolvente = id_tipo_seccion_envolvente_padr";
		
		try {
			pstmt = this.conn.prepareStatement(query);
			//where
			rs = pstmt.executeQuery();
			resp = new ArrayList<SeccionTO>();
			int idPadre;
			
			while(rs.next()){
				SeccionTO seccion = new SeccionTO();
				
				nombreSeccionPadre = rs.getString(1);
				idPadre = rs.getInt(2);
				
				seccion.setIdSeccion(idPadre);
				seccion.setIdSeccionPadre(idPadre);
				seccion.setIdTipoSeccion(idPadre);
				
				seccion.setNombre_seccion_padre(nombreSeccionPadre); 
				seccion.setNombreTipo(nombreSeccionPadre);
				
				seccion.setSeccionesHijo(this.obtenerSeccionesHijoEdificio(idPadre, idEdificio, nombreSeccionPadre));
			 
				if(seccion!=null){ 
					seccion.setComposicion( materiales.obtenerComposicionSeccionEdificio(idPadre, idEdificio) );
				
					seccion = materiales.obtenerParametroComposicion(seccion, idEdificio);
				}
			
				resp.add(seccion);
				
			}
			
			
			rs.close();
			pstmt.close();
			
			
			
		} catch (SQLException e) {
			UtilLog.registrar(e);
		 
		}
		finally{
			if(pstmt!=null){
				try{
					if(rs!=null)
						rs.close();
					pstmt.close();
				}catch (SQLException sqle){
					UtilLog.registrar(sqle);
				} 
			}
		}

		
		
		return resp;
	}
	
	@Override
	public List<SeccionTO> obtenerSeccionesHijoEdificio(int idSeccionPadre, int idEdificio, String nombreSeccionPadre) {
		List<SeccionTO> resp = null;
		
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String query 			= "SELECT s.id_seccion, " +
										 "s.id_tipo_seccion_envolvente, " +
										 "s.area_seccion, " +
										 "ts.nombre_seccion_envolvente " +
								  "FROM secciones_envolvente_edificio s " +
								  "INNER JOIN tipo_seccion_envolvente ts ON ts.id_tipo_seccion_envolvente = s.id_tipo_seccion_envolvente " +
								  "WHERE s.id_edificio = ? and s.id_tipo_seccion_envolvente_padr =?;";
		
		try {
			pstmt = this.conn.prepareStatement(query);
			pstmt.setInt(1, idEdificio);
			pstmt.setInt(2, idSeccionPadre);
			
			rs = pstmt.executeQuery();
			resp = new ArrayList<SeccionTO>();
			
			while (rs.next()){
				
				SeccionTO s = new SeccionTO();
				s.setIdSeccion(rs.getInt(1));
				s.setIdTipoSeccion(rs.getInt(2));
				s.setArea(rs.getFloat(3));
				s.setNombreTipo(rs.getString(4));
				s.setIdSeccionPadre(idSeccionPadre);
				s.setNombre_seccion_padre(nombreSeccionPadre);
				
				resp.add(s);
			}
			
			pstmt.close();
			rs.close();
			
		} catch (Exception e) {
			UtilLog.registrar(e);
		}finally{
			if(pstmt!=null){
				try {
					pstmt.close();
					if(rs!=null)
						rs.close();
				} catch (SQLException sqle) {
					UtilLog.registrar(sqle);
				}
			}
		}
		
		return resp;
	}

	public int obtenerSiguienteIdSeccion()
	{
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        int resp = -1;
        String query = "SELECT nextval('tipo_seccion_envolvente_id_tipo_seccion_envolvente_seq') as NEXTVAL";
        
        try
        {                        
            pstmt = conn.prepareStatement(query);            
            rs = pstmt.executeQuery();
            
            if(rs.next())
                resp = rs.getInt("NEXTVAL");
            
            rs.close();
            pstmt.close();
            
        }
        catch (SQLException sqle) {
        	UtilLog.registrar(sqle);
        }
        finally{
            if (pstmt != null) {
                  try {
                       pstmt.close();
                       rs.close();
                  } catch (SQLException e) {
                       e.printStackTrace();
                  }
            }
        }        
        return resp;
    }

}
